package com.glamour.hlcity.component.task.impl;

import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import com.glamour.hlcity.common.enums.ErrorCodeEnum;
import com.glamour.hlcity.componenet.task.factory.RunnableFactory;
import com.glamour.hlcity.component.task.common.TaskException;

/**
 * 
 * @author zhaoxing.liuzx
 *
 */
public class DaemonThread implements Runnable, ApplicationListener{
	
	private final static Log LOG=LogFactory.getLog(DaemonThread.class);
	//默认最大是10个线程
	private final static Integer MAX_RUNNABLE_UNIT=10;
	//核心运行线程单元个数为10
	private final static Integer CORE_RUNNABLE_UNIT=10;
	
	//一天秒数
	private final static Integer ONE_DAY_SEC=24*60*60;
	//线程池队列长度
	private final static Integer THREAD_SIZE=12;
    //线程池接收新执行单元阀值
	private final static Integer HUNGRY_SIZE=2;
	//命令个数
	private final static Integer QUENE_SIZE=10;
	
	//无命令休息时常（毫秒）
	private final static Integer NO_EXECUTE_UNIT_WAIT_MILLIS=2000;
	
	private RunnableFactory runnableFactory;
	
	
	public void setRunnableFactory(RunnableFactory runnableFactory) {
		this.runnableFactory = runnableFactory;
	}


	@Override
	public void run() {
		BlockingQueue<Runnable> queue=new ArrayBlockingQueue<Runnable>(THREAD_SIZE);
		ThreadPoolExecutor executor=new ThreadPoolExecutor(CORE_RUNNABLE_UNIT, MAX_RUNNABLE_UNIT, ONE_DAY_SEC, TimeUnit.SECONDS, queue);
		while(true){
			try{
				//确保队列可以容纳10条命令
				if(queue.size()<=HUNGRY_SIZE){
					List<Runnable> runnableList=runnableFactory.queryRunnableUnit(QUENE_SIZE);
					for(Runnable runnable:runnableList){
						executor.execute(runnable);
					}
				}else{
					Thread.sleep(NO_EXECUTE_UNIT_WAIT_MILLIS);
				}
				
			}catch(Exception e){
				LOG.error("分发器分发执行过程中发生异常",new TaskException(ErrorCodeEnum.M010002));
			}
		}
	}

	/**
	 * 初始化启动
	 */
	public void init(){
		Thread thread=new Thread(this);
		thread.start();
		
	}


	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		 if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
	            if (LOG.isInfoEnabled()) {
	                LOG.info("The task dispatcher started on spring started.");
	            }
	            //暂时注释掉
	           //init();
	        }
	}
	

}
